package nl.twingate.processrevivor.logic;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

/**
 * This Broadcastreceiver listens to the "APP_SOS" intent. 
 * If this intent gets broadcasted, this receiver will be launched.
 * This receiver will then activate an asynctask which will revive the process which called "APP_SOS".
 * There are some paramters needed to revive a task:
 * - reviveApp : A boolean to tell us that if we want to revive this app
 * - packageName : the packagename of the app to revive
 * - mainActivityPath : The path to the main activity of this app
 * - extraInfo (optional) : A String that contains any extra info you want! =)
 * - timoutBeforeRevive(optional) : The amount of ms to wait for us to revice an app
 * 
 * @author Marijn Oosterveld
 *
 */
public class ExitReceiver extends BroadcastReceiver {

	private String tag = "ExitReceiver";
	
	
	//Constants, these cannot be empty
	//TODO: load these parameters from the resources somehow?
	private String DEVELOPER_EMAIL_ADDRESS = "example@twingate.nl";
	private boolean POST_TO_SERVER = true;
	private String POST_SERVER_URL = "http://www.twingate.nl/devicesupport.php";
	
	
	//Private variables
	private boolean reviveApp = false; // This boolean will control if an app gets revived
	private String sourcePackageName = ""; //The PackageName is needed to revive this process
	private String sourceMainActivityName = ""; //The activity that you want tot start
	private int timoutBeforeRevive = 2000; // A timeout taht you want to give the app to revice itself, before reviving it.
	private String extraInfo = ""; // Any extra info about the SOS 
	private String subject = "";
	

	
	
	@Override
	public void onReceive(Context source, Intent sourceIntent) {
		
		Log.e(tag, "WARNING: APP_SOS RECEIVED for '" + sourcePackageName + "'");	
		
		//First up, parse the information we got from our sourceIntent
		// These variables are needed to revive the process you want
		subject = safeParse(sourceIntent.getStringExtra("subject"), "");
		reviveApp = sourceIntent.getBooleanExtra("reviveApp", false);
		sourcePackageName = safeParse(sourceIntent.getStringExtra("packageName"), "");
		sourceMainActivityName = safeParse(sourceIntent.getStringExtra("mainActivityPath"), "");
		extraInfo = safeParse(sourceIntent.getStringExtra("extraInfo"), "");
		
		//Parse the optional parameters
		timoutBeforeRevive = sourceIntent.getIntExtra("timeoutBeforeRevive", 2000);
		
		//post the crash information to the server
		if(POST_TO_SERVER){
			postToHTTPServer();
		}
		
		//If APP_SOS received a true reviveApp flag, revive the app.
		if(reviveApp){
		 Log.i(tag, "Wants to revive : " + sourcePackageName + " using " + sourceMainActivityName);
			if(sourcePackageName != null && sourceMainActivityName != null){
				if(!sourcePackageName.equals("") && !sourceMainActivityName.equals("")){
					//TODO: post all our info to this intent as well
					new ReviveProcessesByReceiverTask(source,sourcePackageName,sourceMainActivityName, timoutBeforeRevive).execute();
				}else{
					Log.e(tag, "sourcePackageName and/or sourceMainActivityName was empty");
				}
			}else{
				Log.e(tag, "sourcePackageName and/or sourceMainActivityName was null");
			}
		}
	}
	
	/**
	 * Parses a String. Never returns null
	 * @param in : Returned Stringor null from a method
	 * @return : Returns in if its not null, def if it is.
	 */
	private String safeParse(String in, String def){
		if(in != null){
			return in;
		}else{
			return "";
		}
	}
	
	/**
	 * Post information to an HTTP server
	 * 
	 * Things that will get posted:
	 * - DEVELOPER_EMAIL_ADDRESS -> POST parameter "email"
	 * - reviveApp -> Posts if processRevivor will revive this app
	 * - packageName : the packagename of the app to revive -> POST parameter "appinfo"
     * - mainActivityPath : The path to the main activity of this app -> POST parameter "appinfo"
     * - extraInfo : A String that contains any extra info you want! =) -> POST parameter extrainfo
	 * 
	 */
	public void postToHTTPServer(){
		
		// Create a new HttpClient and Post Header
	    HttpClient httpclient = new DefaultHttpClient();
	    HttpPost httppost = new HttpPost(POST_SERVER_URL);

	    try {
	        // Add your data
	        List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
	        nameValuePairs.add(new BasicNameValuePair("email", DEVELOPER_EMAIL_ADDRESS));
	        nameValuePairs.add(new BasicNameValuePair("subject", "" + subject));
	        nameValuePairs.add(new BasicNameValuePair("reviveApp", "" + reviveApp));
	        nameValuePairs.add(new BasicNameValuePair("packageName", sourcePackageName));
	        nameValuePairs.add(new BasicNameValuePair("mainActivityPath", sourceMainActivityName));
	        nameValuePairs.add(new BasicNameValuePair("extraInfo", extraInfo));
	        httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

	        // Execute HTTP Post Request
	        HttpResponse response = httpclient.execute(httppost);
	        
	    } catch (ClientProtocolException e) {
	    	Log.e(tag, e.getMessage());
	    } catch (IOException e) {
	        Log.e(tag, e.getMessage());
	    }
		
	}

}
